//@author A0101119Y
#include "FileReader.h"

using namespace Twentyfifth;
using namespace std;

FileReader::FileReader() {
	openFile(FILE_DATABANK);
}

FileReader::FileReader(string customFile) {
	openFile(customFile);
}

FileReader::~FileReader() {
	closeFile();
}

bool FileReader::isOpen() {
	return file.is_open();
}

void FileReader::openFile(string fileName) {
	if (file.is_open()) {
		file.close();
	}
	file.open(fileName, fstream::in);
	return;
}

//
// task readers
//

vector<Task> FileReader::readTasksFromFile() {
	vector<Task> taskVector;
	while (hasNextTask()) {
		try {
			Task t = getNextTask();
			taskVector.push_back(t);
		}
		catch (Status::StatusCode a) {
			if (a = Status::ERR_OTHER) {
				break;
			}
		}
	}
	return taskVector;
}

bool FileReader::hasNextTask() {
	return file.good();
}

Task FileReader::getNextTask() {
	Task task;
	string line;
	getline(file, line);
	string label = getLabel(line);
	string value = getValue(line);
	if (label != LABEL_ID) {
		throw Status::ERR_OTHER;
	} else {
		task.setId(stoi(value));
		while (getline(file, line)) {
			if (line == BLANK_STRING) {
				break;
			}
			label = getLabel(line);
			value = getValue(line);
			if (label == LABEL_TYPE) {
				Task::TaskType type = Task::identifyTaskType(value);
				task.setTaskType(type);
			} else if (label == LABEL_IS_DONE) {
				if (value == VALUE_BOOL_TRUE) {
					task.setDone();
				}
			} else if (label == LABEL_DESCRIPTION) {
				task.setDescription(value);
			} else if (label == LABEL_VENUE) {
				task.setVenue(value);
			} else if (label == LABEL_START) {
				DateTime start = parseDateTimeFromString(value);
				task.setStart(start);
			} else if (label == LABEL_END) {
				DateTime end = parseDateTimeFromString(value);
				task.setEnd(end);
			} else if (label == LABEL_DEADLINE) {
				DateTime deadline = parseDateTimeFromString(value);
				task.setDeadline(deadline);
			} else if (label == LABEL_GCAL_ID) {
				task.setGCalId(value);
			} else if (label == LABEL_IS_DELETED) {
				if (value == VALUE_BOOL_TRUE) {
					task.setDeleted(true);
				}
			} else if (label == LABEL_LAST_UPDATED) {
				DateTime lastupdated = parseDateTimeFromString(value);
				task.setLastUpdated(lastupdated);
			} else if (label == LABEL_FULL_DAY) {
				if (value == VALUE_BOOL_TRUE) {
					task.setFullDay(true);
				}
			}
		}
	}
	return task;
}

//
// line readers
//

string FileReader::getLabel(string line) {
	string label;
	size_t separatorPosition = getSeparatorPosition(line);
	label = line.substr(POS_START_OF_LABEL, separatorPosition - POS_START_OF_LABEL);
	return label;
}

string FileReader::getValue(string line) {
	string value;
	size_t separatorPosition = getSeparatorPosition(line);
	value = line.substr(separatorPosition + 1, string::npos);
	return value;
}

size_t FileReader::getSeparatorPosition(string line) {
	size_t pos = line.find(LABEL_SEPARATOR);
	return pos;
}

//
// non-string variable parsers
//

DateTime FileReader::parseDateTimeFromString(string line) {
	DateTime dt;
	smatch match;
	if (regex_search(line, match, REGEX_TIMESTAMP)) {
		dt.setDay(stoi(match[3]));
		dt.setMonth(stoi(match[2]));
		dt.setYear(stoi(match[1]));
		dt.setHour(stoi(match[4]));
		dt.setMinute(stoi(match[5]));
		dt.setSecond(stoi(match[6]));
	}
	return dt;
}